/**
 * CornellBox implementation
 */

#include "CornellBoxScene.h"

/////////////////////////////////////////////////

CornellBoxScene::CornellBoxScene()
{
	EntityPtr cBox(new Entity(createCornellBox()));
	// Try to center the box around the y-axis 
	Vec3 t(2.78, 0.0, 0.0);
	cBox->getModel()->translate(t);
	addEntity(cBox);
	//EntityPtr sBox(new Entity(createShortBlock()));
	//addEntity(sBox);
    //sBox->getModel()->sendToCard();
   
	ModelPtr m(new Model("bunny"));
    m->loadOBJ("bin/models/bunny1.obj");
	//m->scale(0.015);
	m->scale(15.0);
    m->setBoundingCoords();
    //m->setDrawBoundingBox(true);
    //m->sendToCard();
	EntityPtr bunny1(new Entity(m));
	bunny1->setPosition(Vec3(0.0, 0.6, -4.0));
	bunny1->setRotSpeed(20.0);
	for (int i=0; i<1; i++) {
	    addEntity(bunny1);
	}

	EntityPtr bunny2(new Entity(m));
	bunny2->setPosition(Vec3(2.0, 0.6, -4.0));
	bunny2->setRotSpeed(20.0);
    //addEntity(bunny2);
	
	EntityPtr bunny3(new Entity(m));
	bunny3->setPosition(Vec3(-2.0, 0.6, -4.0));
	bunny3->setRotSpeed(20.0);
    //addEntity(bunny3);

  	//ModelPtr floor_model(new Model("floor"));
    //floor_model->loadOBJ("bin/models/floor_robby.obj");
	//EntityPtr floor(new Entity(floor_model));
    //addEntity(floor);
 
	// The light...
	Vec3 verts[4];
	Vec3 att(1.0, 0.0, 0.0);
	verts[0] = Vec3(-3.430, 5.488, -2.270) + t;
	verts[1] = Vec3(-3.430, 5.488, -3.320) + t;
	verts[2] = Vec3(-2.130, 5.488, -3.320) + t;
	verts[3] = Vec3(-2.130, 5.488, -2.270) + t;
	LightPtr l(new Light(Material(), verts, Vec3(0.0, -1.0, 0.0), Vec3(0.0, 0.0, -1.0), 45.0, 2.0, att));
	addLight(l);
	
}

/////////////////////////////////////////////////

ModelPtr CornellBoxScene::createCornellBox()
{
	ModelPtr m(new Model("Cornell Box"));

	// Floor
	PartPtr floor(new Part());
	floor->mat.diffuse = Vec3(0.8, 0.8, 0.8);
	floor->verts.push_back(Vec3(-5.528, 0.0, 0.0));   
	floor->verts.push_back(Vec3(0.0, 0.0, 0.0));
	floor->verts.push_back(Vec3(0.0, 0.0, -5.592));
	floor->verts.push_back(Vec3(-5.496, 0.0, -5.592));

	floor->norms.push_back(Vec3(0.0, 1.0, 0.0));

	floor->tris.push_back(Triangle(0, 1, 2, 0, 0, 0));
	floor->tris.push_back(Triangle(2, 3, 0, 0, 0, 0));
	m->parts.push_back(floor);

	// Front wall
    ///*
	PartPtr front(new Part());
	front->mat.diffuse = Vec3(0.8, 0.8, 0.8);
	front->verts.push_back(Vec3(-5.496, 0.0,   0.000)); 
	front->verts.push_back(Vec3( 0.0,   0.0,   0.000));
	front->verts.push_back(Vec3( 0.0,   5.488, 0.000));
	front->verts.push_back(Vec3(-5.560, 5.488, 0.000));

	front->norms.push_back(Vec3(0.0, 0.0, -1.0));

	front->tris.push_back(Triangle(2, 1, 0, 0, 0, 0));
	front->tris.push_back(Triangle(0, 3, 2, 0, 0, 0));

	m->parts.push_back(front);
    //*/


	// Back wall
	PartPtr back(new Part());
	back->mat.diffuse = Vec3(0.8, 0.8, 0.8);
	back->verts.push_back(Vec3(-5.496, 0.0, -5.592)); 
	back->verts.push_back(Vec3(0.0, 0.0, -5.592));
	back->verts.push_back(Vec3(0.0, 5.488, -5.592));
	back->verts.push_back(Vec3(-5.560, 5.488, -5.592));

	back->norms.push_back(Vec3(0.0, 0.0, 1.0));

	back->tris.push_back(Triangle(0, 1, 2, 0, 0, 0));
	back->tris.push_back(Triangle(2, 3, 0, 0, 0, 0));

	m->parts.push_back(back);

	// Ceiling
	PartPtr ceil(new Part());
	ceil->mat.diffuse = Vec3(0.8, 0.8, 0.8);
	ceil->verts.push_back(Vec3(-5.560, 5.488, 0.0));
	ceil->verts.push_back(Vec3(-5.560, 5.488, -5.592));
	ceil->verts.push_back(Vec3(0.0, 5.488, -5.592));
	ceil->verts.push_back(Vec3(0.0, 5.488, 0.0));

	ceil->norms.push_back(Vec3(0.0, -1.0, 0.0));

	ceil->tris.push_back(Triangle(0, 1, 2, 0, 0, 0));
	ceil->tris.push_back(Triangle(2, 3, 0, 0, 0, 0));

	m->parts.push_back(ceil);

	// Right wall
	PartPtr right(new Part());
	right->mat.diffuse = Vec3(0.0, 1.0, 0.0);
	right->verts.push_back(Vec3(0.0, 0.0, -5.592));
	right->verts.push_back(Vec3(0.0, 0.0, 0.0));
	right->verts.push_back(Vec3(0.0, 5.488, 0.0));
	right->verts.push_back(Vec3(0.0, 5.488, -5.592));	

	right->norms.push_back(Vec3(-1.0, 0.0, 0.0));

	right->tris.push_back(Triangle(0, 1, 2, 0, 0, 0));
	right->tris.push_back(Triangle(2, 3, 0, 0, 0, 0));

	m->parts.push_back(right);

	// Left wall
	PartPtr left(new Part());
	left->mat.diffuse = Vec3(1.0, 0.0, 0.0);
	left->verts.push_back(Vec3(-5.528, 0.0, 0.0));
	left->verts.push_back(Vec3(-5.496, 0.0, -5.592));
	left->verts.push_back(Vec3(-5.560, 5.488, -5.592));
	left->verts.push_back(Vec3(-5.560, 5.488, 0.0));

	left->norms.push_back(Vec3(1.0, 0.0, 0.0));

	left->tris.push_back(Triangle(0, 1, 2, 0, 0, 0));
	left->tris.push_back(Triangle(2, 3, 0, 0, 0, 0));
	
	m->parts.push_back(left);

//	m->sendToCard();
	return m;
}

////////////////////////////////////////////////

ModelPtr CornellBoxScene::createShortBlock()
{
	ModelPtr m(new Model("Short Block"));

    // top
    PartPtr top(new Part());
    top->mat.diffuse = Vec3(1.0,1.0,1.0);
    top->verts.push_back(Vec3( -1.300,  1.650, -0.650));
    top->verts.push_back(Vec3( -0.820,  1.650, -2.250));
    top->verts.push_back(Vec3( -2.400,  1.650, -2.720));
    top->verts.push_back(Vec3( -2.900,  1.650, -1.140));

    top->norms.push_back(Vec3(0.0,1.0,0.0));

	top->tris.push_back(Triangle(0, 1, 2, 0, 0, 0));
	top->tris.push_back(Triangle(2, 3, 0, 0, 0, 0));
    
    m->parts.push_back(top);
	
    // left side
    PartPtr s0(new Part());
    s0->mat.diffuse = Vec3(1.0,1.0,1.0);

	s0->verts.push_back(Vec3(-2.900,   0.0, -1.140));
	s0->verts.push_back(Vec3(-2.900, 1.650, -1.140));
	s0->verts.push_back(Vec3(-2.400, 1.650, -2.720));
	s0->verts.push_back(Vec3(-2.400,   0.0, -2.720));
		
	// Calculate normal
	Vec3 norm = (s0->verts[1] - s0->verts[0])^(s0->verts[3] - s0->verts[0]);
	s0->norms.push_back(norm);

	s0->tris.push_back(Triangle(0, 1, 2, 0, 0, 0));
	s0->tris.push_back(Triangle(2, 3, 0, 0, 0, 0));
    
    m->parts.push_back(s0);

	// front side
    PartPtr s1(new Part());
    s1->mat.diffuse = Vec3(1.0,1.0,1.0);

	s1->verts.push_back(Vec3(-1.300,   0.0, -.650));
	s1->verts.push_back(Vec3(-1.300, 1.650, -.650));
	s1->verts.push_back(Vec3(-2.900, 1.650, -1.140));
	s1->verts.push_back(Vec3(-2.900,   0.0, -1.140));
		
	// Calculate normal
	norm = (s1->verts[1] - s1->verts[0])^(s1->verts[3] - s1->verts[0]);
	s1->norms.push_back(norm);

	s1->tris.push_back(Triangle(0, 1, 2, 0, 0, 0));
	s1->tris.push_back(Triangle(2, 3, 0, 0, 0, 0));
    
    m->parts.push_back(s1);

	// right side
    PartPtr s2(new Part());
    s2->mat.diffuse = Vec3(1.0,1.0,1.0);

	s2->verts.push_back(Vec3( -.820,   0.0, -2.250));
	s2->verts.push_back(Vec3( -.820, 1.650, -2.250));
	s2->verts.push_back(Vec3(-1.300, 1.650,  -.650));
	s2->verts.push_back(Vec3(-1.300,   0.0,  -.650));

	// Calculate normal
	norm = (s2->verts[1] - s2->verts[0])^(s2->verts[3] - s2->verts[0]);
	s2->norms.push_back(norm);

	s2->tris.push_back(Triangle(0, 1, 2, 0, 0, 0));
	s2->tris.push_back(Triangle(2, 3, 0, 0, 0, 0));
    
    m->parts.push_back(s2);

	// back side
    PartPtr s3(new Part());
    s3->mat.diffuse = Vec3(1.0,1.0,1.0);

	s3->verts.push_back(Vec3(-2.400,   0.0, -2.720));
	s3->verts.push_back(Vec3(-2.400, 1.650, -2.720));
	s3->verts.push_back(Vec3( -.820, 1.650, -2.250));
	s3->verts.push_back(Vec3( -.820,   0.0, -2.250));
	
	// Calculate normal
	norm = (s3->verts[1] - s3->verts[0])^(s3->verts[3] - s3->verts[0]);
	s3->norms.push_back(norm);

	s3->tris.push_back(Triangle(0, 1, 2, 0, 0, 0));
	s3->tris.push_back(Triangle(2, 3, 0, 0, 0, 0));
    
    m->parts.push_back(s3);

	return m;
}

